//  HDPullDownRefreshControl.swift
//  HDSwfitWeibo
//
//  Created by wty on 16/4/15.
//  Copyright © 2016年 wty. All rights reserved.
//

import UIKit
//刷新控件的高度
let   HDRefreshControlHeight:CGFloat = 60
//设置刷新的三种状态
enum HDPullDownRefreshControlStatus : Int{
    case Normal //  箭头向下  下拉刷新
    case PullToRefresh //箭头朝上 释放刷新
    case Refreshing //  正在刷新
}
class HDPullDownRefreshControl: UIView {
//定义下刷新的闭包
    var pullToRefreshHandler:(()->Void)?
//记录上一次的状态 为了判断从 Refreshing 到Normal(结束刷新)状态 隐藏状态栏  如果上一次状态是 Refreshing   才隐藏
    private var oldStauts:HDPullDownRefreshControlStatus?
//创建超级父控件
    private var  superScrollView : UIScrollView?
//根据状态 设置控件状态
    private var currentStatus:HDPullDownRefreshControlStatus = HDPullDownRefreshControlStatus.Normal {
        didSet {
          
            switch currentStatus {
            case .Normal:
                //显示箭头 隐藏转轮
                arrow.hidden = false
                rotationView.hidden = true
                //修改消息为下拉刷新
                messageLabel.text = "下拉刷新"
                //清空之前的箭头tranform设置
                 UIView.animateWithDuration(animationCurtation, animations: { () -> Void in
                    self.arrow.transform = CGAffineTransformIdentity
                 })
                if  oldStauts == HDPullDownRefreshControlStatus.Refreshing{
                    //结束刷新后需要隐蔽刷新控件
                    UIView.animateWithDuration(animationCurtation, animations: { () -> Void in
                        self.superScrollView?.contentInset.top -= HDRefreshControlHeight
                    })
                }
   
            case .PullToRefresh:
                //修改消息为 释放刷新
                  messageLabel.text = "释放刷新"
                //旋转箭头
                UIView.animateWithDuration(animationCurtation, animations: { () -> Void in
                    self.arrow.transform = CGAffineTransformMakeRotation(CGFloat(M_PI - 0.001))
                })
        
            case .Refreshing:
                //隐藏箭头  显示转轮
                arrow.hidden = true
                rotationView.hidden = false
                messageLabel.text = "正在刷新..."
                //用基本动画让转轮旋转
                let rotation = CABasicAnimation(keyPath: "transform.rotation")
                rotation.toValue = M_PI*2
                rotation.duration = 0.5
                rotation.repeatCount = MAXFLOAT
                rotation.removedOnCompletion = false
                rotationView.layer.addAnimation(rotation, forKey:  "rotation")
                //因为一放手tableView 就会弹回去所以要重新设置内边距 让刷新条可显示  用动画然后持续一段时间
                UIView.animateWithDuration(animationCurtation, animations: { () -> Void in
                    self.superScrollView!.contentInset.top += HDRefreshControlHeight
                })
                //调用闭包
                pullToRefreshHandler!()
        
            }
            //记录上一次状态
            oldStauts = currentStatus
            
        }
    }
//开始刷新方法
    func beginRefreshing(){
        currentStatus = .Refreshing
    }
//结束刷新方法
    func endRefreshing(){
        currentStatus = .Normal

    }

//MARK -初始化方法
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    override init(frame: CGRect) {
        //设置frame
        let  newframe =  CGRect(x: 0, y: -HDRefreshControlHeight, width:ScreenW, height:  HDRefreshControlHeight)
        super.init(frame: newframe)
        prepareUI()
    }
//MARK -添加子控件以及约束
    private func prepareUI(){
        //添加子控件
        addSubview(arrow)
        addSubview(rotationView)
        addSubview(messageLabel)
        rotationView.hidden  = true
        //添加约束
        arrow.snp_makeConstraints { (make) -> Void in
            make.centerX.equalTo(self).offset(-30)
            make.centerY.equalTo(self)
        }
        rotationView.snp_makeConstraints { (make) -> Void in
            make.centerY.equalTo(arrow)
            make.centerX.equalTo(arrow)
        }
        messageLabel.snp_makeConstraints { (make) -> Void in
            make.leading.equalTo(arrow.snp_trailing).offset(10)
            make.centerY.equalTo(arrow)
        }
    }

    //当控件被添加到父控件中都会调用这个方法  可以拿到父控件
    override func willMoveToSuperview(newSuperview: UIView?) {
        super.willMoveToSuperview(newSuperview)
        //判断父控件是不是UIScrollView及其之类  如果是就记录起来
        if  let scrollView = newSuperview as? UIScrollView {
            superScrollView = scrollView
            //使用KVO来监听scrollView的滚动
            //要监听谁属性 就用谁来调用
            //observer:谁来处理监听事件
            //forKeyPath:  想监听谁的属性
            //options: 监听选项 新值和老值
            //context: 上下文
            //1.注册监听
            superScrollView?.addObserver(self, forKeyPath: "contentOffset", options: [], context: nil)
        }
    }
    //2.实现监听回调  就可以监听到tableView的滚动  来改变刷新状态
    override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>) {
        //1.如果处于拖动状态  那就就是在箭头向下或者向上两种状态转换
        if superScrollView!.dragging {
            //如果小于了内边距和刷新条的大小  就是箭头向下状态
            //为了避免频繁的改变状态
            if currentStatus == .PullToRefresh&&superScrollView?.contentOffset.y > -( superScrollView!.contentInset.top + HDRefreshControlHeight) {
                currentStatus = HDPullDownRefreshControlStatus.Normal
            }else if  currentStatus == .Normal&&superScrollView?.contentOffset.y <= -( superScrollView!.contentInset.top + HDRefreshControlHeight)      {
                //如果是大于内边距和刷新条的大小   就是箭头向上状态
                currentStatus = HDPullDownRefreshControlStatus.PullToRefresh
       
            }
        }else if currentStatus == .PullToRefresh{
            //如果停止拖动  判断当前状态  如果是箭头向下状态  就转换为刷新状态
            currentStatus = HDPullDownRefreshControlStatus.Refreshing

        }
    }
    
    //3.移除监听
    deinit {
        removeObserver(self, forKeyPath: "contentOffset")
    }
 
    
//MARK -懒加载子控件
    //箭头
    private var arrow:UIImageView = UIImageView(image: UIImage(named: "tableview_pull_refresh"))
    //小转轮
    private var rotationView:UIImageView = UIImageView(image: UIImage(named: "tableview_loading"))
    //文字
    private var messageLabel :UILabel = {
        let  label = UILabel()
        label.font = UIFont.systemFontOfSize(HDNormalLabelFontSize)
        label.textColor = UIColor.darkGrayColor()
        label.text = "下拉刷新"
        label.sizeToFit()
        return label
    }()

}
